perm filename ELFER.SAI[S,HE] blob sn#566027 filedate 1982-05-09 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	The following procedures Allow input and output on the ELF
C00012 ENDMK
C⊗;
COMMENT The following procedures Allow input and output on the ELF;

ENTRY ELFINI,ELFREL,ELFIN,ELFIN_NXM,ELFOUT,ELFBKI,ELFBKO,POWERFAIL;

BEGIN
 Require "⊂⊃<>" Delimiters;
 Define ! = ⊂COMMENT⊃;
 Define crlf = "'15&'12";
 Integer MTAPE_AND_ELFCHAN;	! This integer contains the MTAPE UUO and ;
				! the channel number used by the elf;
 Define ELFMTAPE(ADDR) = "CODE(MTAPE_AND_ELFCHAN,ADDR)";
				! The above will cause the MTAPE UUO to be called;
				! with instruction and data at ADDR;
 Define QUICKBIT = '400;	! This bit means "do risky but fast ELF I/O";
 Integer elfchan;		! Elfchan is the channel number used for Elf I/O;
 External Integer _SKIP_;	! Used to indicate error conditons;

Internal Integer Procedure CALLUUO(String UUO;Integer AC;Reference Integer ADDR);
   BEGIN "CALLUUO"
    Integer UUOCODE;
    UUOCODE←CALL(CVSIX(UUO),"CALLIT");
    IF UUOCODE=0 THEN PRINT("NO SUCH UUO: ",UUO)
	ELSE RETURN(CODE(UUOCODE+(AC LSH 23),ADDR));
   END "CALLUUO";

Simple Integer Procedure IOWD(Integer N, Addr);
	Return(((-N) LAND '777777) LSH 18 + (Addr -1));

PROCEDURE ELFERR (STRING caller; INTEGER addr);
  BEGIN
  INTEGER ELF_STATUS;
  PRINT("ELF error - ");
  CALLUUO("GETSTS",ELFCHAN,ELF_STATUS);	! Get status of 11 interface;
  IF ELF_STATUS LAND '40000 THEN PRINT("NXM"&crlf);
  IF ELF_STATUS LAND '20000 THEN PRINT("Couldn't get unibus"&crlf);
  IF ELF_STATUS LAND '4000 THEN PRINT("Unibus reset in progress"&crlf);
  IF ELF_STATUS LAND '2000 THEN PRINT("Parity error"&crlf);
  IF ELF_STATUS LAND '1000 THEN PRINT("Interface is hung"&crlf);
  IF ¬(ELF_STATUS LAND '67000) THEN PRINT("ELF status = ",CVOS(ELF_STATUS),crlf);
  USERERR(0,1,caller & " address = " & CVOS(addr));
  SETSTS(ELFCHAN,'17);	! Reset status of 11 interface;
  END;


Internal Procedure ELFINI;
  ! ELFINI opens the device ELF on the channel elfchan;
  Begin "ELFINI"
    Integer EOF,	! EOF = 0 if open is successful;
	    bchr,	! Needed by open procedure;
	    cnt;

    elfchan ← GETCHAN;
    IF elfchan = -1 Then USERERR(0,1,"NO AVAILABLE CHANNELS FOR ELF")
    ELSE Begin
	OPEN(elfchan,"ELF",'17,0,0,cnt, bchr,EOF);	! Opens ELF on elfcahn in ;
							! dump mode '17;
!	IF EOF ≠ 0 THEN USERERR(0,1,"OPEN OF ELF FAILED");
        MTAPE_AND_ELFCHAN ← '072000000000 + (elfchan LSH 23);	! Mtape UUO for ELF;
    End;
								! one 11 wd/10 wd;
  End "ELFINI";

Internal Procedure ELFREL;
   ! ELFREL closes the device elf and releases the associated channel;
   Begin "ELFREL"

	CLOSE(elfchan);    RELEASE(elfchan);
   End "ELFREL";

Internal Procedure RISKON;
  ! RISKON sets the "risky but quick" mode for the elf;
  Begin "RISKON"
    SETSTS(Elfchan,GETSTS(Elfchan) LOR QUICKBIT)
  End "RISKON";

Internal Procedure RISKOFF;
  ! RISKOFF clears that mode;
  Begin "RISKOFF"
    SETSTS(Elfchan,GETSTS(Elfchan) LAND (LNOT QUICKBIT))
  End "RISKOFF";

Internal Procedure ELFOUT(Integer wordaddr, word);
  ! ELFOUT puts the given word at the specified word address (not byte address);
  Begin "ELFOUT"
    OWN Integer Array INSTR[1:2];
    Define POKE = "'003000000000";
    INSTR[1] ← POKE + (wordaddr);	! First word contains opcode and bus addr;
    INSTR[2] ← word;			! Second word is data;
    ELFMTAPE(INSTR[1]);			! MTAPE UUO;
    IF NOT _SKIP_ Then ELFERR("NO OUTPUT TO ELF",wordaddr);
  End "ELFOUT";

Internal Integer Procedure ELFIN(Integer wordaddr);
  ! ELFIN inputs a 16 bit value at location specified by the wordaddr through 
          elf;
  Begin "ELFIN"
    OWN Integer Array INSTR[1:2];
    Define PEEK = "'002000000000";
    INSTR[1] ← PEEK + (wordaddr);	! First word contains opcode and bus addr;
    ELFMTAPE(INSTR[1]);			! MTAPE UUO;
    If Not _SKIP_ Then ELFERR("INPUT FROM ELF FAILED",wordaddr);
    Return(INSTR[2]);			! Retrieved word put at second word;
  End "ELFIN";

Internal Procedure POWERFAIL;
  ! POWERFAIL does a power fail trap on the PDP-11.;
  Begin "POWERFAIL"
    OWN Integer Array INSTR[1:2];
    Define PWRTRP = "'005000000000";
    INSTR[1] ← PWRTRP;			! First word contains opcode;
    ELFMTAPE(INSTR[1]);			! MTAPE UUO;
    If Not _SKIP_ Then ELFERR("ATTEMPT TO RESET FAILED",0);
  End "POWERFAIL";

Internal Integer Procedure ELFIN_NXM(Integer wordaddr);
  ! ELFIN_NXM inputs a 16 bit value at location specified by the wordaddr through 
          elf.  If a NXM error occurs this routine continues;
  Begin "ELFIN_NXM"
    OWN Integer Array INSTR[1:2];
    Integer elf_status;
    Define PEEK = "'002000000000";
    INSTR[1] ← PEEK + (wordaddr);	! First word contains opcode and bus addr;
    ELFMTAPE(INSTR[1]);			! MTAPE UUO;
    If Not _SKIP_ Then BEGIN
	CALLUUO("GETSTS",ELFCHAN,ELF_STATUS); ! Get status of 11 interface;
	IF (ELF_STATUS LAND '40000) OR  ¬(ELF_STATUS LAND '67000) THEN BEGIN
	  ! Igonore NXM's and null error status;
	    INSTR[2] ← 0;
	    SETSTS(ELFCHAN,'17);  ! Reset status of 11 interface;
	END
	ELSE ELFERR("INPUT FROM ELF FAILED",wordaddr)
    END;
    Return(INSTR[2]);			! Retrieved word put at second word;
  End "ELFIN_NXM";

Internal Procedure ELFBKO(Integer busaddr, nwords; Integer Array data; 
			  Integer usetbits (0));
  ! ELFBKO ouputs the data contained in the Array data to the given unibus address;
  Begin "ELFBKO"
    Integer USETOWD, OUTIOWD;
    
     USETOWD ← '400000400000 LOR (busaddr) LOR usetbits; ! Initilize ELF for output;
     CALLUUO("USETO",elfchan,USETOWD);
     OUTIOWD ← IOWD(nwords, LOCATION(data[ARRINFO(DATA,1)]));	! specify blk param;
     CALLUUO("OUT",elfchan,OUTIOWD);			! Output Array to 11;
     IF _SKIP_ THEN ELFERR("BLOCK OUTPUT THROUGH ELF FAILED",busaddr);
  End "ELFBKO";

Internal Procedure ELFBKI(Integer busaddr, nwords, dataaddress, usetbits (0));
  ! ELFBKI Fills the array data with nwords starting at the given unibus address;
  Begin "ELFBKI"
    Integer USETIWD, INIOWD;
    USETIWD ← '400000400000 LOR busaddr LOR usetbits;	! Initialize ELF for input;
    CALLUUO("USETI",elfchan,USETIWD);
    INIOWD ← IOWD(nwords, dataaddress);	! Describe Block;
    CALLUUO("IN",elfchan, INIOWD);			! Input Array;
    IF _SKIP_ THEN ELFERR("BLOCK INPUT THROUGH ELF FAILED",busaddr);
 End "ELFBKI";

END;